package com.ixuestar.controller;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ixuestar.dao.IxuestarCloudELMapper;
import com.ixuestar.dao.IxuestarParentsMapper;
import com.ixuestar.dao.SmartTerminalMapper;
import com.ixuestar.entity.MemberAndParents;
import com.ixuestar.entity.MembershipInfo;
import com.ixuestar.entity.MembershipReRecord;
import com.ixuestar.entity.MembershipVipInfo;
import com.ixuestar.entity.Membershiparents;
import com.ixuestar.entity.RechargeRecord;
import com.ixuestar.entity.YxWxuser;
import com.ixuestar.entity.Yxtorder;
import com.ixuestar.entity.YxtorderPay;
import com.ixuestar.service.SmartTerminalService;
import com.ixuestar.util.ReturnResult;
import com.ixuestar.util.SHA;
import com.ixuestar.wxutil.GetwxOpenId;
import com.ixuestar.wxutil.HttpUtil;
import com.ixuestar.wxutil.PayCommonUtil;
import com.ixuestar.wxutil.PayConfigUtil;
import com.ixuestar.wxutil.Signatrue;
import com.ixuestar.wxutil.XMLUtil;

@CrossOrigin
@RestController
@RequestMapping(value = "/wxPay",method = RequestMethod.POST)
public class WeixinController extends BaseController {


    private final Logger logger = Logger.getLogger(WeixinController.class);

    @Autowired
    private SmartTerminalService smartTerminalService;
    
    @Autowired
    private SmartTerminalMapper smartTerminalMapper;
    
    @Autowired
    private IxuestarParentsMapper ixuestarParentsMapper;
    
    @Autowired
    private IxuestarCloudELMapper ixuestarCloudELMapper;

    ///////////////爱学思达会员充值////////////////////
    
    
	/**
	 * @method 
	 * @param jsonObject
	 * @param response
	 * @return
	 */
	@RequestMapping("/getWxIxuestarGOpenId")
	@ResponseBody
	public Map<String, Object> getWxIxuestarGOpenId(@RequestBody JSONObject jsonObject,HttpServletResponse response){
		//创建返回参数
		Map<String, Object> map = null;
		try {
			logger.info("-----------进入getWxSessionKey接口-------------");
			String code = jsonObject.getString("code");
			//执行接口
			final String openId = GetwxOpenId.getWxGOpenId(code);
			jsonObject.put("openId", openId);
			jsonObject.remove("code");
			//
			map = ReturnResult.correctResult(jsonObject);
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
			map = ReturnResult.wrongResult();
		}
		return map;
	}
    
    
    
    
    @RequestMapping(value = "/membeRecharge", produces = "Application/json; charset=utf-8")
    @ResponseBody
    public Map<String, Object> mobOrderH5(@RequestBody JSONObject jsObject, HttpServletRequest req, HttpServletResponse resp) {
        this.setCrossHeader(resp);
        Map<String, Object> map = null;

        String ixmId = jsObject.getString("ixmId");
        String openId = jsObject.getString("openId");
        double amount = jsObject.getDouble("amount");

        try {
        	/**
        	 * 首先判断用户是否存在
        	 *  1、如果存在就继续进行充值
        	 *  2、如果不存在就返回给用户信息提示
        	 */
           Map<String, Object> parm = new HashMap<String, Object>();
           parm.put("lineKey", "ixmId");
           parm.put("lineValue", ixmId);
           MembershipInfo membershipInfo = smartTerminalService.getMembershipInfo(parm);
	        if (membershipInfo != null) {

	                int total = (int) (amount * 100.0);
	                logger.info("total---------" + total);
	                // 3. 调用统一下单接口，获取prepay_id
	                String appid = PayConfigUtil.ixuestarwx_APP_ID_G; // appid
	                String mch_id = PayConfigUtil.ixuestarwx_MCH_ID_G; // 商业号
	                String key = PayConfigUtil.ixuestarwx_API_KEY_G; // key
	
	                String currTime = PayCommonUtil.getCurrTime();
	                String strRandom = PayCommonUtil.buildRandom(4) + "";
	                String strTime = currTime.substring(8, currTime.length());
	                String nonce_str = strTime + strRandom;
	
	                String body = "i学思达高中智能教辅平台(i学星充值)"; // 商品名称
	                
	                String ixeId = "" + new Date().getTime() + (int)(Math.random()*10);
	                String out_trade_no = ixmId + "_" + ixeId;// 订单号
	
	                // 获取发起电脑 ip
	                String spbill_create_ip = HttpUtil.localIp();// PayConfigUtil.CREATE_IP;
	                // 回调接口
	                String notify_url = PayConfigUtil.ixuestarwx_NOTIFY_ORDER_G;
	                String trade_type = "JSAPI";
	                String device_info = "i学思达高中智能教辅平台";

	                SortedMap<String, Object> packageParams = new TreeMap<String, Object>();
	                packageParams.put("appid", appid);
	                packageParams.put("mch_id", mch_id);
	                packageParams.put("device_info", device_info);
	                packageParams.put("nonce_str", nonce_str);
	                packageParams.put("body", body);
	                packageParams.put("out_trade_no", out_trade_no);
	                packageParams.put("total_fee", total + "");
	                packageParams.put("spbill_create_ip", spbill_create_ip);
	                packageParams.put("notify_url", notify_url);
	                packageParams.put("trade_type", trade_type);
	                logger.info("packageParams:" + packageParams);
	                //app支付不需要传入openid
	                packageParams.put("openid", openId);
	
	                String sign = PayCommonUtil.createSign("UTF-8", packageParams, key);
	                packageParams.put("sign", sign);
	//		            packageParams.put("scene_info", scene_info);
	
	                String requestXML = PayCommonUtil.getRequestXml(packageParams);
	                logger.info(requestXML);
	
	                String resXml = HttpUtil.postData(PayConfigUtil.ixuestarwx_UNIORDER_URL, requestXML);
	                logger.info("ResultXML:\n" + resXml);
	
	                String prepay_id = "";
	                String code_url = "";
	                Map<?,?> wxResultmap = XMLUtil.doXMLParse(resXml);
	                String return_code = (String) wxResultmap.get("return_code");
	                String result_code = (String) wxResultmap.get("result_code");
	                if (return_code.equals("SUCCESS") && result_code.equals("SUCCESS")) {
	                    trade_type = (String) wxResultmap.get("trade_type");
	                    prepay_id = (String) wxResultmap.get("prepay_id");
	                    code_url = (String) wxResultmap.get("code_url");
	                    logger.info("return_code:" + return_code);
	                    logger.info("prepay_id:" + prepay_id);
	                }
	                /*
				                 * 公众号id appId 是 String(16) wx8888888888888888
				                 * 商户注册具有支付权限的公众号成功后即可获得 时间戳 timeStamp 是 String(32)
	                 * 1414561699 当前的时间，其他详见时间戳规则 随机字符串 nonceStr 是 String(32)
	                 * 5K8264ILTKCH16CQ2502SI8ZNMTM67VS 随机字符串，不长于32位。推荐随机数生成算法
				                 * 订单详情扩展字符串 package 是 String(128) prepay_id=123456789
				                 * 统一下单接口返回的prepay_id参数值，提交格式如：prepay_id=*** 签名方式 signType 是
	                 * String(32) MD5 签名算法，暂支持MD5 签名 paySign 是 String(64)
	                 * C380BEC2BFD727A4B6845133519F3AD6 签名，详见签名生成算法
	                 */
	
	
	                strTime = currTime.substring(8, currTime.length());
	                strRandom = PayCommonUtil.buildRandom(4) + "";
	                String nonceStr = strTime + strRandom;
	
	                String signType = "MD5";
	
	                SortedMap<String, Object> packageParams2 = new TreeMap<String, Object>();
	                String ts = "" + ((new Date()).getTime()) / 1000L;
	                packageParams2.put("appId", appid);
	                packageParams2.put("noncestr", nonceStr);
	                packageParams2.put("package", "prepay_id=" + prepay_id);
	                packageParams2.put("code_url", code_url);
	                packageParams2.put("signType", signType);
	                packageParams2.put("timestamp", ts);
	                SortedMap<String, Object> packageParams3 = new TreeMap<String, Object>();
	                packageParams3.put("appId", appid);
	                packageParams3.put("nonceStr", nonceStr);
	                packageParams3.put("package", "prepay_id=" + prepay_id);
	//		            packageParams3.put("code_url", code_url);
	                packageParams3.put("signType", signType);
	                packageParams3.put("timeStamp", ts);
	                //获取sign
	
	                logger.info("appId:" + appid);
	                logger.info("nonceStr:" + nonceStr);
	                logger.info("package:" + "prepay_id=" + prepay_id);
	                logger.info("signType:" + signType);
	                logger.info("timeStamp:" + ts);
	                logger.info("key:" + key);
	
	                String paySign = PayCommonUtil.createSign("UTF-8", packageParams3, key);
	
	                packageParams2.put("paySign", paySign);
	                packageParams2.put("success", true);
	                //格式转化
	                JSONObject parseObject = JSON.parseObject(JSON.toJSONString(packageParams2));
	                map = ReturnResult.correctResult(parseObject);
	        }else {
				map = ReturnResult.otherResult(1, "用户信息不存在，请核实信息后重新填写");
			}
        } catch (Exception e) {
            e.printStackTrace();
            map = ReturnResult.wrongResult();
        }
        return map;
    }

    @RequestMapping("/getConfig")
    @ResponseBody
    public Map<String, Object> getConfig(@RequestBody JSONObject jsonObject, HttpServletResponse response) {
        this.setCrossHeader(response);
        Map<String, Object> map = new HashMap<String, Object>();

        String url = jsonObject.getString("url");

        try {
//            logger.info("=======" + url + "=======");
            //生成随机字符串
            String currTime = PayCommonUtil.getCurrTime();
            String strTime = currTime.substring(8);
            String strRandom = PayCommonUtil.buildRandom(4) + "";
            String nonceStr = strTime + strRandom;
            //生成时间戳
            String ts = "" + ((new Date()).getTime()) / 1000L;
            //生成签名
            String accessToken = Signatrue.getAccessToken();
            logger.info("=======" + accessToken + "=======");
            String jsapiTicket = Signatrue.getTicket(accessToken);
            logger.info("===========" + jsapiTicket + "===========");
//            String url = "http://qa.travbao.com/goabraod/view/Other/Picc/index.html";
            //拼接
            String tsa = "jsapi_ticket=" + jsapiTicket + "&noncestr=" + nonceStr + "&timestamp=" + ts + "&url=" + url;
            //生成签名
            String signature = new SHA().getDigestOfString(tsa.getBytes());

            JSONObject packageParams2 = new JSONObject();
            packageParams2.put("timestamp", ts);
            packageParams2.put("nonceStr", nonceStr);
            packageParams2.put("signature", signature);
            packageParams2.put("appId", PayConfigUtil.ixuestarwx_APP_ID_G);
            //返回参数
            map.put("code", 0);
            map.put("data", packageParams2);
            map.put("message", "获取成功！");
            map.put("success", true);
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
            map.put("code", -1);
            map.put("success", false);
            map.put("message", "获取失败！");
        }
        return map;
    }

    @SuppressWarnings("unchecked")
	@RequestMapping("/wxInfoCallBack")
    @ResponseBody
    public void wxInfoCallBack(HttpServletRequest request,
                              HttpServletResponse response) throws Exception {
        logger.info("into notifyOrder");
        // 读取参数
        InputStream inputStream;
        StringBuffer sb = new StringBuffer();
        inputStream = request.getInputStream();
        String s;
        BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
        while ((s = in.readLine()) != null) {
            sb.append(s);
        }
        in.close();
        inputStream.close();

        // 解析xml成map
//        Map<String, String> map = new HashMap<String, String>();
        logger.info("Weixin Notify received:\n" + sb.toString());
        Map<String, String> map = XMLUtil.doXMLParse(sb.toString());

        // 过滤空 设置 TreeMap
        SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
        Iterator<?> it = map.keySet().iterator();
        while (it.hasNext()) {
            String parameter = (String) it.next();
            String parameterValue = map.get(parameter);

            String v = "";
            if (null != parameterValue) {
                v = parameterValue.trim();
            }
            packageParams.put(parameter, v);
        }

        // 账号信息
        String key = PayConfigUtil.ixuestarwx_API_KEY_G; // key

        logger.info(packageParams);

        // 判断签名是否正确
        if (PayCommonUtil.isTenpaySign("UTF-8", packageParams, key)) {
            // ------------------------------
            // 处理业务开始
            // ------------------------------
            String resXml = "";
            if ("SUCCESS".equals((String) packageParams.get("result_code"))) {
                // ////////执行自己的业务逻辑////////////////
                String mch_id = (String) packageParams.get("mch_id");
                String out_trade_no = (String) packageParams.get("out_trade_no");
                String total_fee = (String) packageParams.get("total_fee");
                String transaction_id = (String) packageParams.get("transaction_id");
                String end_time = (String) packageParams.get("time_end");

                logger.info("mch_id:" + mch_id);
                logger.info("out_trade_no:" + out_trade_no);//订单号
                logger.info("total_fee:" + total_fee);
                
                try {
                	//获取ixmId
                	String[] arr = out_trade_no.split("_");
                	String ixmId = arr[0];
                	String ixeId = "ixe" + arr[1];
                    double totalAmount = Double.parseDouble(total_fee)/100.00;
                    //写入充值记录
                    //4、写入充值记录
                    RechargeRecord rechargeRecord = new RechargeRecord();
                    //创建id
//						String ixeId = "ixe" + new Date().getTime() + (int)(Math.random()*10);
                    String ixeCreatetime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
                    rechargeRecord.setIxeId(ixeId);
                    rechargeRecord.setIxeAmount(totalAmount);
                    rechargeRecord.setIxeTransactionNumber(transaction_id);
                    rechargeRecord.setIxeRechargeTime(end_time);
                    rechargeRecord.setIxeRechargeMethod("微信支付");
                    rechargeRecord.setIxeCreatetime(ixeCreatetime);
                    smartTerminalMapper.writeRechargeRecord(rechargeRecord);
                    //5、写入充值关系表
                    MembershipReRecord membershipReRecord = new MembershipReRecord();
                    //创建id和时间
                    String ixmrId =  "ixmr" + new Date().getTime() + (int)(Math.random()*10);
                    String ixmrCreatetime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
                    membershipReRecord.setIxmrId(ixmrId);
                    membershipReRecord.setIxmId(ixmId);
                    membershipReRecord.setIxeId(ixeId);
                    membershipReRecord.setIxmrCreatetime(ixmrCreatetime);
                    smartTerminalMapper.writeMembershipReRecord(membershipReRecord);
                    //判断充值是否超过500
					//判断是否够资格成为会员
					double atotal = 0.00;
					Map<String,Object> hashMap = new HashMap<>();
					hashMap.put("lineKey", "ixmId");
					hashMap.put("lineValue", ixmId);
					List<MembershipReRecord> membershipReRecords = smartTerminalMapper.getMembershipReRecords(hashMap);
					for (int i = 0; i < membershipReRecords.size(); i++) {
						//获取充值记录对象
						MembershipReRecord membershipReRecord2 = membershipReRecords.get(i);
						String ixeId2 = membershipReRecord2.getIxeId();
						hashMap.put("lineKey", "ixeId");
						hashMap.put("lineValue", ixeId2);
						RechargeRecord rechargeRecords = smartTerminalMapper.getRechargeRecords(hashMap);
						atotal = atotal + rechargeRecords.getIxeAmount();
					}
                    //创建vip或者写入会员金额
					if ((int)atotal>=300  && (int)atotal>=500) {
						//创建vip信息
						MembershipVipInfo membershipVipInfo = new MembershipVipInfo();
						String imvId = "imv" + new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()) + (int)(Math.random()*10);
						String imvCreatetime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
						membershipVipInfo.setImvId(imvId);
						membershipVipInfo.setIxmId(ixmId);
						membershipVipInfo.setImvType(2);;
						membershipVipInfo.setImvCreatetime(imvCreatetime);
						ixuestarParentsMapper.writeMembershipVipInfo(membershipVipInfo);
					}else if ((int)atotal >= 500) {
						//创建vip信息
						MembershipVipInfo membershipVipInfo = new MembershipVipInfo();
						String imvId = "imv" + new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()) + (int)(Math.random()*10);
						String imvCreatetime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
						membershipVipInfo.setImvId(imvId);
						membershipVipInfo.setIxmId(ixmId);
						membershipVipInfo.setImvType(1);;
						membershipVipInfo.setImvCreatetime(imvCreatetime);
						ixuestarParentsMapper.writeMembershipVipInfo(membershipVipInfo);
					}else {
//	    				Map<String, Object> hashMap = new HashMap<>();
	    				hashMap.put("lineKey", "ixmId");
	    				hashMap.put("lineValue", ixmId);
	    				MembershipInfo membershipInfo = smartTerminalMapper.getMembershipInfo(hashMap);
	    				double ixmAmount = membershipInfo.getIxmAmount();
	    				//5、写入会员剩余金额
	    				if (totalAmount==100.0) {
	    					ixmAmount = ixmAmount + totalAmount*10;
						}else if (totalAmount==200.0) {
							ixmAmount = ixmAmount + totalAmount*10 + 100.0;
						}else if (totalAmount==500.0) {
							ixmAmount = ixmAmount + totalAmount*10 + 300.0;
						}else {
							ixmAmount = ixmAmount + totalAmount*10;
						}
						membershipInfo.setIxmAmount(ixmAmount);
						smartTerminalMapper.updatePassword(membershipInfo);
					}

				} catch (Exception e) {
					// TODO: handle exception
					e.printStackTrace();
				}
                //支付成功
                logger.info("--------Pay Success!---------");
                // 通知微信.异步确认成功.必写.不然会一直通知后台.八次之后就认为交易失败了.
                resXml = "<xml>"
                        + "<return_code><![CDATA[SUCCESS]]></return_code>"
                        + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
            } else {
                logger.info("Pay Fail, error code： " + packageParams.get("err_code"));
                resXml = "<xml>"
                        + "<return_code><![CDATA[FAIL]]></return_code>"
                        + "<return_msg><![CDATA[Report empty]]></return_msg>"
                        + "</xml> ";
            }
        logger.info("notifyVenueOrder resXml： " + resXml);
         //------------------------------
         //处理业务完毕
         //------------------------------
            BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
            out.write(resXml.getBytes());
            out.flush();
            out.close();
        } else {
            logger.info("signature checking fail");
        }

        logger.info("----------sb.toString()-"+sb.toString()+"------------");
    }
    
    
    @RequestMapping(value = "/parentPayment")
    @ResponseBody
    public Map<String, Object> createUnifiedOrder(@RequestBody JSONObject jsonObject, HttpServletResponse response) {
        logger.info("微信 统一下单 接口调用");
        //设置最终返回对象
        Map<String, Object> map = new HashMap<>();

        int amount = jsonObject.getInteger("amount");
        String ixmpId = jsonObject.getString("ixmpId");
        try {
        	//获取用户openId
        	Map<String, Object> hashMap = new HashMap<>();
        	hashMap.put("lineKey", "ixmpId");
        	hashMap.put("lineValue", ixmpId);
        	Membershiparents membershiparents = ixuestarParentsMapper.getMembershiparents(hashMap);
        	if (membershiparents!=null) {
            	String openId = membershiparents.getIxmpOpenid();
                // 账号信息
                String appid = PayConfigUtil.ixuestarwx_APP_ID_J; // appid
                //出国宝旅行商户号信息
                String mch_id = PayConfigUtil.ixuestarwx_MCH_ID_G; // 商业号
                String key = PayConfigUtil.ixuestarwx_API_KEY_G; // key
                //接口调用总金额单位为分换算一下(测试金额改成1,单位为分则是0.01,根据自己业务场景判断是转换成float类型还是int类型)
                String total = ((int) (amount * 100.0))+"";
                //创建hashmap(用户获得签名)
                SortedMap<String, Object> paraMap = new TreeMap<String, Object>();
                //设置body变量 (支付成功显示在微信支付 商品详情中)
                String body = "i学思达高中智能教辅平台（会员充值）";
                //设置随机字符串
                String currTime = PayCommonUtil.getCurrTime();
                String strTime = currTime.substring(8);
                String strRandom = PayCommonUtil.buildRandom(4) + "";
                String nonceStr = strTime + strRandom;
                
                String ixeId = "ixe" + new Date().getTime() + (int)(Math.random()*10);
                //设置商户订单号
                final String outTradeNo = ixmpId.substring(4)+"_"+ixeId;
                // 获取发起电脑 ip
                String spbill_create_ip = HttpUtil.localIp();//PayConfigUtil.CREATE_IP;
                // 回调接口
                String notify_url = PayConfigUtil.ixuestarwx_NOTIFY_ORDER_J;
                //PC扫码发起类型SSSSSSSSSSSSSSSSSSSSSSS

                //设置请求参数(小程序ID)
                paraMap.put("appid", appid);
                //设置请求参数(商户号)
                paraMap.put("mch_id", mch_id);
                //设置请求参数(随机字符串)
                paraMap.put("nonce_str", nonceStr);
                //设置请求参数(商品描述)
                paraMap.put("body", body);
                //设置请求参数(商户订单号)
                paraMap.put("out_trade_no", outTradeNo);
                //设置请求参数(总金额)
                paraMap.put("total_fee", total);
                //设置请求参数(终端IP)
                paraMap.put("spbill_create_ip", spbill_create_ip);
                //设置请求参数(通知地址)
                paraMap.put("notify_url", notify_url);
                //设置请求参数(交易类型)
                paraMap.put("trade_type", "JSAPI");
                //设置请求参数(openid)(在接口文档中 该参数 是否必填项 但是一定要注意 如果交易类型设置成'JSAPI'则必须传入openid)
                paraMap.put("openid", openId);
                //调用逻辑传入参数按照字段名的 ASCII 码从小到大排序（字典序）
                String sign = PayCommonUtil.createSign("UTF-8", paraMap, key);
                paraMap.put("sign", sign);
                //将参数 编写XML格式
                String requestXML = PayCommonUtil.getRequestXml(paraMap);
                logger.info(requestXML);

                String resXml = HttpUtil.postData(PayConfigUtil.ixuestarwx_UNIORDER_URL, requestXML);
                logger.info("ResultXML:\n" + resXml);

                String prepay_id = "";
//                String trade_type = "";
                Map<?,?> wxResultmap = XMLUtil.doXMLParse(resXml);
                String return_code = (String) wxResultmap.get("return_code");
                String result_code = (String) wxResultmap.get("result_code");
                if (return_code.equals("SUCCESS") && result_code.equals("SUCCESS")) {
                	String trade_type = (String) wxResultmap.get("trade_type");
                    prepay_id = (String) wxResultmap.get("prepay_id");
                    logger.info("return_code:" + return_code);
                    logger.info("trade_type:" + trade_type);
                    logger.info("prepay_id:" + prepay_id);
                }
                //生成时间戳
                strTime = currTime.substring(8);
                strRandom = PayCommonUtil.buildRandom(4) + "";
                String nonce_Str = strTime + strRandom;
                //加密方式
                String signType = "MD5";

                SortedMap<String, Object> packageParams2 = new TreeMap<String, Object>();
                String ts = "" + ((new Date()).getTime()) / 1000L;
                packageParams2.put("appId", appid);
                packageParams2.put("timeStamp", ts);
                packageParams2.put("nonceStr", nonce_Str);
                packageParams2.put("package", "prepay_id=" + prepay_id);
                packageParams2.put("signType", signType);

                logger.info("appId:" + appid);
                logger.info("nonceStr:" + nonceStr);
                logger.info("package:" + "prepay_id=" + prepay_id);
                logger.info("signType:" + signType);
                logger.info("timeStamp:" + ts);
                logger.info("key:" + key);

                String paySign = PayCommonUtil.createSign("UTF-8", packageParams2, key);
                logger.info("paySign:" + paySign);

                packageParams2.put("sign", paySign);
                packageParams2.put("success", true);

                map.put("data", packageParams2);
                map.put("message", "获取成功！");
                map.put("success", true);
                map.put("code", 0);
                //
			}
        	return map;
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
            map.put("data", new HashMap<>());
            map.put("message", "获取失败");
            map.put("success", false);

            return map;
        }
    }
    
    @SuppressWarnings({"unchecked", "rawtypes"})
    @RequestMapping("/parentnotifyOrder")
    @ResponseBody
    public void notifyOrdera(HttpServletRequest request, HttpServletResponse response) throws Exception {
        logger.info("into notifyOrder");
        // 读取参数
        InputStream inputStream;
        StringBuffer sb = new StringBuffer();
        inputStream = request.getInputStream();
        String s;
        BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
        while ((s = in.readLine()) != null) {
            sb.append(s);
        }
        in.close();
        inputStream.close();

        // 解析xml成map
        Map<String, String> map = new HashMap<String, String>();
        logger.info("Weixin Notify received:\n" + sb.toString());
        map = XMLUtil.doXMLParse(sb.toString());

        // 过滤空 设置 TreeMap
        SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
        Iterator it = map.keySet().iterator();
        while (it.hasNext()) {
            String parameter = (String) it.next();
            String parameterValue = map.get(parameter);

            String v = "";
            if (null != parameterValue) {
                v = parameterValue.trim();
            }
            packageParams.put(parameter, v);
        }

        // 账号信息
        String key = PayConfigUtil.ixuestarwx_API_KEY_G; // key

        logger.info(packageParams);
        // 判断签名是否正确
        if (PayCommonUtil.isTenpaySign("UTF-8", packageParams, key)) {
	            // ------------------------------
	            // 处理业务开始
	            // ------------------------------
        		String resXml = "";
	            if ("SUCCESS".equals(packageParams.get("result_code"))) {
	                // 这里是支付成功
	                // ////////执行自己的业务逻辑////////////////
	                String mch_id = (String) packageParams.get("mch_id");
	                String out_trade_no = (String) packageParams.get("out_trade_no");
	                String total_fee = (String) packageParams.get("total_fee");
	                String transaction_id = (String) packageParams.get("transaction_id");
	                String end_time = (String) packageParams.get("time_end");
	                
	                logger.info("mch_id:" + mch_id);
	                logger.info("out_trade_no:" + out_trade_no);//订单号
	                logger.info("total_fee:" + total_fee);
	                double totalAmount = Double.parseDouble(total_fee)/100.00;
	                String[] arr = out_trade_no.split("_");
	                String ixmpId = "ixmp" + arr[0];
	                String ixeId = arr[1];
	                //获取父母绑定的ixmId
	                Map<String, Object> hashMap = new HashMap<>();
	                hashMap.put("lineKey", "ixmpId");
	                hashMap.put("lineValue", ixmpId);
	                MemberAndParents memberAndParents = ixuestarParentsMapper.getMemberAndParents(hashMap).get(0);
	                if (memberAndParents!=null) {
						String ixmId = memberAndParents.getIxmId();
						
		                //////////执行自己的业务逻辑////////////////
						//4、写入充值记录
						RechargeRecord rechargeRecord = new RechargeRecord();
						//创建id
//						String ixeId = "ixe" + new Date().getTime() + (int)(Math.random()*10);
						String ixeCreatetime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
						rechargeRecord.setIxeId(ixeId);
						rechargeRecord.setIxeAmount(totalAmount);
						rechargeRecord.setIxeTransactionNumber(transaction_id);
						rechargeRecord.setIxeRechargeTime(end_time);
						rechargeRecord.setIxeRechargeMethod("微信支付");
						rechargeRecord.setIxeCreatetime(ixeCreatetime);
						smartTerminalMapper.writeRechargeRecord(rechargeRecord);
						//创建vip信息
						MembershipVipInfo membershipVipInfo = new MembershipVipInfo();
						String imvId = "imv" + new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()) + (int)(Math.random()*10);
						String imvCreatetime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
						membershipVipInfo.setImvId(imvId);
						membershipVipInfo.setIxmId(ixmId);
						if ((int)totalAmount >= 300 && (int)totalAmount < 500) {
							membershipVipInfo.setImvType(2);							
						}else if ((int)totalAmount >= 500) {
							membershipVipInfo.setImvType(1);
							
						}
						membershipVipInfo.setImvCreatetime(imvCreatetime);
						ixuestarParentsMapper.writeMembershipVipInfo(membershipVipInfo);
						//6、写入充值关系表
						MembershipReRecord membershipReRecord = new MembershipReRecord();
						//创建id和时间
						String ixmrId =  "ixmr" + new Date().getTime() + (int)(Math.random()*10);
						String ixmrCreatetime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
						membershipReRecord.setIxmrId(ixmrId);
						membershipReRecord.setIxmId(ixmpId);
						membershipReRecord.setIxeId(ixeId);
						membershipReRecord.setIxmrCreatetime(ixmrCreatetime);
						smartTerminalMapper.writeMembershipReRecord(membershipReRecord);
		                //打印支付成功
		                logger.info("--------Pay Success!---------");
		                // 通知微信.异步确认成功.必写.不然会一直通知后台.八次之后就认为交易失败了.
		                resXml = "<xml>"
		                        + "<return_code><![CDATA[SUCCESS]]></return_code>"
		                        + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
					}
//				}
	        } else {
	            logger.info("Pay Fail, error code： " + packageParams.get("err_code"));
	            resXml = "<xml>"
	                    + "<return_code><![CDATA[FAIL]]></return_code>"
	                    + "<return_msg><![CDATA[Report empty]]></return_msg>"
	                    + "</xml> ";
	        }
	        logger.info("notifyVenueOrder resXml： " + resXml);
	        // ------------------------------
	        // 处理业务完毕
	        // ------------------------------
	        BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
	        out.write(resXml.getBytes());
	        out.flush();
	        out.close();
        } else {
            logger.info("signature checking fail");
        }
    }
    
    
    /////////////////////
    ////云易学
    ////////////////////
    @RequestMapping(value = "/cloudelPayment")
    @ResponseBody
    public Map<String, Object> cloudelPayment(@RequestBody JSONObject jsonObject, HttpServletResponse response) {
        logger.info("微信 统一下单 接口调用");
        //设置最终返回对象
        Map<String, Object> map = new HashMap<>();

        String ytoId = jsonObject.getString("ytoId");
        try {
        	//获取用户openId
        	Map<String, Object> hashMap = new HashMap<>();
        	hashMap.put("lineKey", "ytoId");
        	hashMap.put("lineValue", ytoId);
        	Yxtorder yxtorderInfo = ixuestarCloudELMapper.getYxtorderInfo(hashMap);
        	if (yxtorderInfo!=null) {
            	hashMap.put("lineKey", "ytoId");
            	hashMap.put("lineValue", ytoId);
        		String ywId = ixuestarCloudELMapper.getOrderUserObject(hashMap).getYwId();
        		//
            	hashMap.put("lineKey", "ywId");
            	hashMap.put("lineValue", ywId);
            	YxWxuser yxWxuser = ixuestarCloudELMapper.getYxWxuser(hashMap);
            	String openId = yxWxuser.getYwOpenId();
                // 账号信息
                String appid = PayConfigUtil.ixuestarwx_APP_ID_CloudTeacher; // appid
                //出国宝旅行商户号信息
                String mch_id = PayConfigUtil.ixuestarwx_MCH_ID_G; // 商业号
                String key = PayConfigUtil.ixuestarwx_API_KEY_G; // key
                //接口调用总金额单位为分换算一下(测试金额改成1,单位为分则是0.01,根据自己业务场景判断是转换成float类型还是int类型)
                String total = (int)(yxtorderInfo.getYtoAmount()*100)+"";
                //创建hashmap(用户获得签名)
                SortedMap<String, Object> paraMap = new TreeMap<String, Object>();
                //设置body变量 (支付成功显示在微信支付 商品详情中)
                String body = "云易学教辅平台";
                //设置随机字符串
                String currTime = PayCommonUtil.getCurrTime();
                String strTime = currTime.substring(8);
                String strRandom = PayCommonUtil.buildRandom(4) + "";
                String nonceStr = strTime + strRandom;
                
//                String ixeId = "ixe" + new Date().getTime() + (int)(Math.random()*10);
                //设置商户订单号
                final String outTradeNo = ytoId;
                // 获取发起电脑 ip
                String spbill_create_ip = HttpUtil.localIp();//PayConfigUtil.CREATE_IP;
                // 回调接口
                String notify_url = PayConfigUtil.ixuestarwx_NOTIFY_ORDER_Cloud;
                //PC扫码发起类型SSSSSSSSSSSSSSSSSSSSSSS

                //设置请求参数(小程序ID)
                paraMap.put("appid", appid);
                //设置请求参数(商户号)
                paraMap.put("mch_id", mch_id);
                //设置请求参数(随机字符串)
                paraMap.put("nonce_str", nonceStr);
                //设置请求参数(商品描述)
                paraMap.put("body", body);
                //设置请求参数(商户订单号)
                paraMap.put("out_trade_no", outTradeNo);
                //设置请求参数(总金额)
                paraMap.put("total_fee", total);
                //设置请求参数(终端IP)
                paraMap.put("spbill_create_ip", spbill_create_ip);
                //设置请求参数(通知地址)
                paraMap.put("notify_url", notify_url);
                //设置请求参数(交易类型)
                paraMap.put("trade_type", "JSAPI");
                //设置请求参数(openid)(在接口文档中 该参数 是否必填项 但是一定要注意 如果交易类型设置成'JSAPI'则必须传入openid)
                paraMap.put("openid", openId);
                //调用逻辑传入参数按照字段名的 ASCII 码从小到大排序（字典序）
                String sign = PayCommonUtil.createSign("UTF-8", paraMap, key);
                paraMap.put("sign", sign);
                //将参数 编写XML格式
                String requestXML = PayCommonUtil.getRequestXml(paraMap);
                logger.info(requestXML);

                String resXml = HttpUtil.postData(PayConfigUtil.ixuestarwx_UNIORDER_URL, requestXML);
                logger.info("ResultXML:\n" + resXml);

                String prepay_id = "";
//                String trade_type = "";
                Map<?,?> wxResultmap = XMLUtil.doXMLParse(resXml);
                String return_code = (String) wxResultmap.get("return_code");
                String result_code = (String) wxResultmap.get("result_code");
                if (return_code.equals("SUCCESS") && result_code.equals("SUCCESS")) {
                	String trade_type = (String) wxResultmap.get("trade_type");
                    prepay_id = (String) wxResultmap.get("prepay_id");
                    logger.info("return_code:" + return_code);
                    logger.info("trade_type:" + trade_type);
                    logger.info("prepay_id:" + prepay_id);
                }
                //生成时间戳
                strTime = currTime.substring(8);
                strRandom = PayCommonUtil.buildRandom(4) + "";
                String nonce_Str = strTime + strRandom;
                //加密方式
                String signType = "MD5";

                SortedMap<String, Object> packageParams2 = new TreeMap<String, Object>();
                String ts = "" + ((new Date()).getTime()) / 1000L;
                packageParams2.put("appId", appid);
                packageParams2.put("timeStamp", ts);
                packageParams2.put("nonceStr", nonce_Str);
                packageParams2.put("package", "prepay_id=" + prepay_id);
                packageParams2.put("signType", signType);

                logger.info("appId:" + appid);
                logger.info("nonceStr:" + nonceStr);
                logger.info("package:" + "prepay_id=" + prepay_id);
                logger.info("signType:" + signType);
                logger.info("timeStamp:" + ts);
                logger.info("key:" + key);

                String paySign = PayCommonUtil.createSign("UTF-8", packageParams2, key);
                logger.info("paySign:" + paySign);

                packageParams2.put("sign", paySign);
                packageParams2.put("success", true);

                map.put("data", packageParams2);
                map.put("message", "获取成功！");
                map.put("success", true);
                map.put("code", 0);
                //
			}
        	return map;
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
            map.put("data", new HashMap<>());
            map.put("message", "获取失败");
            map.put("success", false);

            return map;
        }
    }
    
    @SuppressWarnings({"unchecked", "rawtypes"})
    @RequestMapping("/cloudelnotifyOrder")
    @ResponseBody
    public void cloudelnotifyOrder(HttpServletRequest request, HttpServletResponse response) throws Exception {
        logger.info("into notifyOrder");
        // 读取参数
        InputStream inputStream;
        StringBuffer sb = new StringBuffer();
        inputStream = request.getInputStream();
        String s;
        BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
        while ((s = in.readLine()) != null) {
            sb.append(s);
        }
        in.close();
        inputStream.close();

        // 解析xml成map
        Map<String, String> map = new HashMap<String, String>();
        logger.info("Weixin Notify received:\n" + sb.toString());
        map = XMLUtil.doXMLParse(sb.toString());

        // 过滤空 设置 TreeMap
        SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
        Iterator it = map.keySet().iterator();
        while (it.hasNext()) {
            String parameter = (String) it.next();
            String parameterValue = map.get(parameter);

            String v = "";
            if (null != parameterValue) {
                v = parameterValue.trim();
            }
            packageParams.put(parameter, v);
        }

        // 账号信息
        String key = PayConfigUtil.ixuestarwx_API_KEY_G; // key

        logger.info(packageParams);
        // 判断签名是否正确
        if (PayCommonUtil.isTenpaySign("UTF-8", packageParams, key)) {
	            // ------------------------------
	            // 处理业务开始
	            // ------------------------------
        		String resXml = "";
	            if ("SUCCESS".equals(packageParams.get("result_code"))) {
	                // 这里是支付成功
	                // ////////执行自己的业务逻辑////////////////
	                String mch_id = (String) packageParams.get("mch_id");
	                String out_trade_no = (String) packageParams.get("out_trade_no");
	                String total_fee = (String) packageParams.get("total_fee");
	                String transaction_id = (String) packageParams.get("transaction_id");
	                String end_time = (String) packageParams.get("time_end");
	                
	                logger.info("mch_id:" + mch_id);
	                logger.info("out_trade_no:" + out_trade_no);//订单号
	                logger.info("total_fee:" + total_fee);
	                //获取订单的信息
	                Map<String, Object> hashMap = new HashMap<>();
	                hashMap.put("lineKey", "ytoId");
	                hashMap.put("lineValue", out_trade_no);
	                Yxtorder yxtorderInfo = ixuestarCloudELMapper.getYxtorderInfo(hashMap);
	                if (yxtorderInfo!=null) {
	                	//修改订单的状态
	                	hashMap.put("lineKey", "ptoPayStatus");
	                	hashMap.put("lineValue", "1");
	                	hashMap.put("ytoId", out_trade_no);
	                	ixuestarCloudELMapper.updateOrderStatus(hashMap);
						
						double ytopAmount = Double.parseDouble(total_fee)/100.00;
		                //////////执行自己的业务逻辑////////////////
						//4、写入充值记录
						YxtorderPay yxtorderPay = new YxtorderPay();
						//创建id
						String ytopId = "ytop" + new Date().getTime() + (int)(Math.random()*10);
						String ytopCreatetime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
						yxtorderPay.setYtopId(ytopId);
						yxtorderPay.setYtopAmount(ytopAmount);
						yxtorderPay.setYtopPaymethod("微信支付");
						yxtorderPay.setYtopRechargeTime(end_time);
						yxtorderPay.setYtopTransactionNumber(transaction_id);
						yxtorderPay.setYtopCreatetime(ytopCreatetime);
						ixuestarCloudELMapper.writeOrderPay(yxtorderPay);
		                //打印支付成功
		                logger.info("--------Pay Success!---------");
		                // 通知微信.异步确认成功.必写.不然会一直通知后台.八次之后就认为交易失败了.
		                resXml = "<xml>"
		                        + "<return_code><![CDATA[SUCCESS]]></return_code>"
		                        + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
					}
//				}
	        } else {
	            logger.info("Pay Fail, error code： " + packageParams.get("err_code"));
	            resXml = "<xml>"
	                    + "<return_code><![CDATA[FAIL]]></return_code>"
	                    + "<return_msg><![CDATA[Report empty]]></return_msg>"
	                    + "</xml> ";
	        }
	        logger.info("notifyVenueOrder resXml： " + resXml);
	        // ------------------------------
	        // 处理业务完毕
	        // ------------------------------
	        BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
	        out.write(resXml.getBytes());
	        out.flush();
	        out.close();
        } else {
            logger.info("signature checking fail");
        }
    }
    
}
